﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Hired
{
    public static class DBEvaluation
    {
        //create evaluation
        public static bool AddEvaluation (Evaluation evl, Jobseeker js, Job job)
        {
            try
            {
                evl.EvaluationID = "tempvalue";
                using (hireddbEntities db = new hireddbEntities())
                {
                    db.Attach(js);
                    db.Attach(job);
                    // need to change database to link Jobseeker to Evaluation instead of JobseekerAccount to Evaluation
                    js.Evaluations.Add(evl);
                    job.Evaluations.Add(evl);

                    db.SaveChanges();
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        //retrieve evaluation
        public static Evaluation RetrieveEvaluation(string retrieveID)
        {
            Evaluation evaluation = null;
            using (hireddbEntities db = new hireddbEntities())
            {
                    evaluation =
                    (from e in db.Evaluations
                    where e.EvaluationID == retrieveID
                    select e).SingleOrDefault();
            }
            return evaluation;
        }
        
        //retrieve evaluation list
        public static List<Evaluation> RetrieveEvaluationList()
        {
            List<Evaluation> evaluationList = null;
            using (hireddbEntities db = new hireddbEntities())
            {
                evaluationList =
                (from e in db.Evaluations
                 select e).ToList();
            }
            return evaluationList;
        }

        //update evaluation
        public static bool UpdateEvaluation(Evaluation evl)
        {
            try
            {
                using (hireddbEntities db = new hireddbEntities())
                {
                    Evaluation evaluationToUpdate = RetrieveEvaluation(evl.EvaluationID);
                    db.Attach(evaluationToUpdate);
                    evaluationToUpdate.IndustryMatch = evl.IndustryMatch;
                    evaluationToUpdate.LocationMatch = evl.LocationMatch;
                    evaluationToUpdate.MinimumQualificationsMatch = evl.MinimumQualificationsMatch;
                    evaluationToUpdate.TitleMatch = evl.TitleMatch;

                    db.SaveChanges();
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        //delete evaluation
        public static bool DeleteEvaluation(Evaluation evl)
        {
            try
            {
                Evaluation evaluationToDelete = RetrieveEvaluation(evl.EvaluationID);
                using (hireddbEntities db = new hireddbEntities())
                {
                    db.Attach(evaluationToDelete);
                    db.DeleteObject(evaluationToDelete);
                    db.SaveChanges();
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        //delete evaluation by evaluationID
        public static bool DeleteEvaluationById(string id)
        {
            try
            {
                Evaluation evaluationToDelete = RetrieveEvaluation(id);
                using (hireddbEntities db = new hireddbEntities())
                {
                    db.Attach(evaluationToDelete);
                    db.DeleteObject(evaluationToDelete);
                    db.SaveChanges();
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public static void PopulateEvaluationTable()
        {
            List<Job> jobList = null;
            List<Jobseeker> jsList = null;
            

            using(hireddbEntities db = new hireddbEntities())
            {
                    jobList =
                    (from j in db.Jobs
                    select j).ToList();

                    jsList =
                    (from js in db.Jobseekers
                     select js).ToList();
            }

            
            foreach (Jobseeker js in jsList)
            {
                foreach (Job j in jobList)
                {
                    bool title = false;
                    bool minQual = false;
                    bool industry = false;
                    //need another method to calculate distance between the jobseeker's address and job's location
                    bool location = false;

                    if (js.PreviousEmployment == j.Title)
                    {
                        title = true;
                    }

                    if (js.EducationLevel == j.MinimumQualifications)
                    {
                        minQual = true;
                    }

                    if (js.Specialization == j.Industry)
                    {
                        industry = true;
                    }

                    Evaluation ev = new Evaluation();
                    ev.JAccountID = js.JAccountID;
                    ev.JobID = j.JobID;
                    ev.TitleMatch = title;
                    ev.MinimumQualificationsMatch = minQual;
                    ev.IndustryMatch = industry;
                    ev.LocationMatch = location;

                    AddEvaluation(ev, js, j);
                }
            }
        }

        public static List<Evaluation> RetrieveListOfAll4MatchEvaluationList(string jAccountID)
        {
            List<Evaluation> all4MatchEvaluationList = new List<Evaluation>();

            using (hireddbEntities db = new hireddbEntities())
            {
                all4MatchEvaluationList =
                (from e in db.Evaluations
                 where e.JAccountID == jAccountID && e.TitleMatch == true && e.MinimumQualificationsMatch == true && e.IndustryMatch == true && e.LocationMatch == true
                 select e).ToList();
            }
           
            return all4MatchEvaluationList;
        }

        public static List<Job> RetrieveListOfAll4MatchJobList(string jAccountID)
        {
            List<Job> all4MatchJobList = new List<Job>();
            List<Evaluation> all4MatchEvaluationList = RetrieveListOfAll4MatchEvaluationList(jAccountID);
            Job single4MatchJob = null;
            using (hireddbEntities db = new hireddbEntities())
            {
                foreach (Evaluation ev in all4MatchEvaluationList)
                {
                    single4MatchJob = DBJob.RetrieveJob(ev.JobID);
                    all4MatchJobList.Add(single4MatchJob);
                }
            }

            return all4MatchJobList;
        }

        public static List<Evaluation> RetrieveListOfAll3MatchEvaluationList_Title_MinQual_Industry(string jAccountID)
        {
            List<Evaluation> all3MatchEvaluationList = new List<Evaluation>();

            using (hireddbEntities db = new hireddbEntities())
            {
                all3MatchEvaluationList =
                (from e in db.Evaluations
                 where e.JAccountID == jAccountID && e.TitleMatch == true && e.MinimumQualificationsMatch == true && e.IndustryMatch == true && e.LocationMatch == false
                 select e).ToList();
            }
            foreach (Evaluation e in all3MatchEvaluationList)
            {
                Console.WriteLine(e.JAccountID);
            }
            return all3MatchEvaluationList;
        }

        public static List<Job> RetrieveListOfAll3MatchJobList_Title_MinQual_Industry(string jAccountID)
        {
            List<Job> all3MatchJobList = new List<Job>();
            List<Evaluation> all3MatchEvaluationList = RetrieveListOfAll3MatchEvaluationList_Title_MinQual_Industry(jAccountID);
            Job single3MatchJob = null;
            using (hireddbEntities db = new hireddbEntities())
            {
                foreach (Evaluation ev in all3MatchEvaluationList)
                {
                    single3MatchJob = DBJob.RetrieveJob(ev.JobID);
                    all3MatchJobList.Add(single3MatchJob);
                }
            }

            return all3MatchJobList;
        }

        public static List<Evaluation> RetrieveListOfAll2MatchEvaluationList_Title_MinQual(string jAccountID)
        {
            List<Evaluation> all2MatchEvaluationList = new List<Evaluation>(); ;

            using (hireddbEntities db = new hireddbEntities())
            {
                all2MatchEvaluationList =
                (from e in db.Evaluations
                 where e.JAccountID == jAccountID && e.TitleMatch == true && e.MinimumQualificationsMatch == true && e.IndustryMatch == false && e.LocationMatch == false
                 select e).ToList();
            }

            return all2MatchEvaluationList;
        }

        public static List<Job> RetrieveListOfAll2MatchJobList_Title_MinQual(string jAccountID)
        {
            List<Job> all2MatchJobList = new List<Job>();
            List<Evaluation> all2MatchEvaluationList = RetrieveListOfAll2MatchEvaluationList_Title_MinQual(jAccountID);
            Job single2MatchJob = null;
            using (hireddbEntities db = new hireddbEntities())
            {
                foreach (Evaluation ev in all2MatchEvaluationList)
                {
                    single2MatchJob = DBJob.RetrieveJob(ev.JobID);
                    all2MatchJobList.Add(single2MatchJob);
                }
            }

            return all2MatchJobList;
        }

        public static List<Evaluation> RetrieveListOfAll2MatchEvaluationList_Title_Industry(string jAccountID)
        {
            List<Evaluation> all2MatchEvaluationList = new List<Evaluation>();

            using (hireddbEntities db = new hireddbEntities())
            {
                all2MatchEvaluationList =
                (from e in db.Evaluations
                 where e.JAccountID == jAccountID && e.TitleMatch == true && e.IndustryMatch == true && e.LocationMatch == false && e.MinimumQualificationsMatch == false
                 select e).ToList();
            }

            return all2MatchEvaluationList;
        }

        public static List<Job> RetrieveListOfAll2MatchJobList_Title_Industry(string jAccountID)
        {
            List<Job> all2MatchJobList = new List<Job>();
            List<Evaluation> all2MatchEvaluationList = RetrieveListOfAll2MatchEvaluationList_Title_Industry(jAccountID);
            Job single2MatchJob = null;
            using (hireddbEntities db = new hireddbEntities())
            {
                foreach (Evaluation ev in all2MatchEvaluationList)
                {
                    single2MatchJob = DBJob.RetrieveJob(ev.JobID);
                    all2MatchJobList.Add(single2MatchJob);
                }
            }

            return all2MatchJobList;
        }

        public static List<Evaluation> RetrieveListOfAll2MatchEvaluationList_Industry_MinQual(string jAccountID)
        {
            List<Evaluation> all2MatchEvaluationList = new List<Evaluation>();

            using (hireddbEntities db = new hireddbEntities())
            {
                all2MatchEvaluationList =
                (from e in db.Evaluations
                 where e.JAccountID == jAccountID && e.IndustryMatch == true && e.MinimumQualificationsMatch == true && e.TitleMatch == false && e.LocationMatch == false
                 select e).ToList();
            }

            return all2MatchEvaluationList;
        }

        public static List<Job> RetrieveListOfAll2MatchJobList_Industry_MinQual(string jAccountID)
        {
            List<Job> all2MatchJobList = new List<Job>();
            List<Evaluation> all2MatchEvaluationList = RetrieveListOfAll2MatchEvaluationList_Industry_MinQual(jAccountID);
            Job single2MatchJob = null;
            using (hireddbEntities db = new hireddbEntities())
            {
                foreach (Evaluation ev in all2MatchEvaluationList)
                {
                    single2MatchJob = DBJob.RetrieveJob(ev.JobID);
                    all2MatchJobList.Add(single2MatchJob);
                }
            }

            return all2MatchJobList;
        }

        public static List<Job> RetrieveMostMatchesToShowList(string jAccountID)
        {
            List<Job> ListOfAllJobsWithMatches = new List<Job>();
            List<Job> all4MatchesList = RetrieveListOfAll4MatchJobList(jAccountID);
            List<Job> all3MatchesList = RetrieveListOfAll3MatchJobList_Title_MinQual_Industry(jAccountID);
            List<Job> all2MatchesList_Title_MinQual = RetrieveListOfAll2MatchJobList_Title_MinQual(jAccountID);
            List<Job> all2MatchesList_Title_Industry = RetrieveListOfAll2MatchJobList_Title_Industry(jAccountID);
            List<Job> all2MatchesList_Industry_MinQual = RetrieveListOfAll2MatchJobList_Industry_MinQual(jAccountID);

            if (all4MatchesList.Count != 0)
            {
                ListOfAllJobsWithMatches.AddRange(all4MatchesList);
            }

            if (all3MatchesList.Count != 0)
            {
                ListOfAllJobsWithMatches.AddRange(all3MatchesList);
            }

            if (all2MatchesList_Title_MinQual.Count != 0)
            {
                ListOfAllJobsWithMatches.AddRange(all2MatchesList_Title_MinQual);
            }

            if (all2MatchesList_Title_Industry.Count != 0)
            {
                ListOfAllJobsWithMatches.AddRange(all2MatchesList_Title_Industry);
            }

            if (all2MatchesList_Industry_MinQual.Count != 0)
            {
                ListOfAllJobsWithMatches.AddRange(all2MatchesList_Industry_MinQual);
            }
            
                List<Job> Top3OfListOfAllJobsWithMatches = new List<Job>();

                
                if (ListOfAllJobsWithMatches.Count == 1)
                {
                    Top3OfListOfAllJobsWithMatches.Add(ListOfAllJobsWithMatches.ElementAt(0));
                }
                else if (ListOfAllJobsWithMatches.Count == 2)
                {
                    Top3OfListOfAllJobsWithMatches.Add(ListOfAllJobsWithMatches.ElementAt(0));
                    Top3OfListOfAllJobsWithMatches.Add(ListOfAllJobsWithMatches.ElementAt(1));
                }
                else if (ListOfAllJobsWithMatches.Count == 3)
                {
                    Top3OfListOfAllJobsWithMatches.Add(ListOfAllJobsWithMatches.ElementAt(0));
                    Top3OfListOfAllJobsWithMatches.Add(ListOfAllJobsWithMatches.ElementAt(1));
                    Top3OfListOfAllJobsWithMatches.Add(ListOfAllJobsWithMatches.ElementAt(2));
                }
                else if (ListOfAllJobsWithMatches.Count == 0)
                {
                    return null;
                }

                return
                Top3OfListOfAllJobsWithMatches;
        }

        public static bool DeleteAllEvaluation(List<Evaluation> evList)
        {
            try
            {
                foreach (Evaluation ev in evList)
                {
                    DeleteEvaluation(ev);
                }

                return true;

            }
            catch (Exception)
            {
                return false;
            }
        }
    }
}